<?php

namespace app\service\wx;

use app\common\exception\MiException;
use app\common\service\CommonSiteConfigService;
use app\extend\MiCurl;
use app\model\site\Site;


class WxMpService
{

    private static ?self $_instance = null;

    private string $appid;
    private string $secret;

    private function __construct(array $config)
    {
        $this->appid = $config['appid'];
        $this->secret = $config['secret'];
    }

    public static function instance(array $config): WxMpService
    {
        if (!self::$_instance){
            self::$_instance = new self($config);
        }
        return self::$_instance;
    }


    /**
     * 获取session_key
     * @param string $code
     * @return array|mixed
     * @throws \Exception
     */
    public function jscode2session(string $code): mixed
    {
        /**
         * code 换取 session_key
         * 这是一个 HTTPS 接口，开发者服务器使用登录凭证 code 获取 session_key 和 openid。
         * 其中 session_key 是对用户数据进行加密签名的密钥。为了自身应用安全，session_key 不应该在网络上传输。
         */
        $url = 'https://api.weixin.qq.com/sns/jscode2session';
        $result = MiCurl::instance()->get($url, [
            'appid' => $this->appid,
            'secret' => $this->secret,
            'grant_type' => 'authorization_code',
            'js_code' => $code
        ])
            ->toArray();

        if ($result['errcode']??0) {
            throw new MiException(json_encode($result));
        }
        return $result;
    }

    /**
     * 将微信小程序返回的session存入静态变量，减少请求次数
     * @param $code
     * @return mixed
     * @throws \Exception
     */
    public function getWxMpSession($code): mixed
    {
        static $session;
        if (empty($session)) {
            // 微信小程序通过code获取session
            $session = $this->jscode2session($code);
        }
        return $session;
    }


    /**
     * 获取access_token
     * @return mixed
     * @throws MiException
     */
    public function getAccessToken(): mixed
    {

        // 请求API获取 access_token
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->appid}&secret={$this->secret}";
        $result = MiCurl::instance()->get($url)->toArray();
        if ($result['errcode']??0) {
            throw new MiException("获取access_token失败：".json_encode($result));
        }

        return $result['access_token'];

    }


    /**
     * 获取手机号
     * @throws \Exception
     */
    public function getPhone($code, $accessToken) {
        $url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" . $accessToken;
        $result = MiCurl::instance()->post($url, json_encode(['code' => $code]))->toArray();
        if ($result['errcode']??0) {
            throw new MiException("获取手机号失败：".json_encode($result));
        }
        return $result['phone_info'];
    }

    /**
     * 获取不限制的小程序码
     * @throws MiException
     * @throws \Exception
     */
    public function getUnlimitedQRCode($data){
        //  "page": "pages/index/index",
        // "scene": "a=1",  // 必填
        // "env_version": "release"     // 版本
        $url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" . $this->getAccessToken();
        $result = MiCurl::instance()->post($url, json_encode($data))->toJson();
        // 验证是否是二进制流
        if (json_decode($result, true) && $result['errcode']??0) {
            throw new MiException("获取二维码失败：".json_encode($result));
        }
        return $result;
    }





}
